/**
 * 
 */
package sg.edu.nus.iss.vmcs.customer;

import java.awt.Frame;

import sg.edu.nus.iss.vmcs.payment.IPaymentClient;
import sg.edu.nus.iss.vmcs.payment.PaymentController;
import sg.edu.nus.iss.vmcs.store.*;
import sg.edu.nus.iss.vmcs.util.*;
import sg.edu.nus.iss.vmcs.system.MainController;
import sg.edu.nus.iss.vmcs.system.SimulatorControlPanel;

public class TransactionController implements IPaymentClient{

	private boolean drinkDispensed;
	private int price;
	private int selection;

	private MainController mainCtrl = null;
	private StoreController storeCtrl = null;

	private DrinksStoreItem drinksStoreItem = null;
	private DrinksBrand drinksBrand = null;
	private CustomerPanel cpanel = null;

	private DispenseController dispenseCtrl;

	private int totalCollected;
	
	private PaymentController paymentController = null;

	public TransactionController(MainController main_controller) {
		drinkDispensed = false;
		price = 0;
		selection = 0;
		mainCtrl = main_controller;
		storeCtrl = mainCtrl.getStoreController();

		dispenseCtrl = new DispenseController(this);
		
		paymentController = new PaymentController(this, mainCtrl);
	}

	public void startTransaction(int identifier) {
		selection = identifier;
		drinksStoreItem = (DrinksStoreItem) mainCtrl.getStoreController()
				.getStoreItem(Store.DRINK, identifier);
		drinksBrand = (DrinksBrand) drinksStoreItem.getContent();
		price = drinksBrand.getCalculatedPrice();
		
		dispenseCtrl.resetCan();
		dispenseCtrl.allowSelection(false);
		
		paymentController.startPayment(price, 120);//Use Payment Facade for collection
	}

	public void processMoneyReceived(int amountReceived) {
		totalCollected = amountReceived;
		if (price <= totalCollected) { // enough money
			completeTransaction();
		} else {
			paymentController.refundPayment();
		}
		
		activateDrinkDispenser();
	}
	
	private void activateDrinkDispenser(){
		dispenseCtrl.allowSelection(true);

		selection = 0;
		drinksStoreItem = null;
		drinksBrand = null;
		price = 0;
	}

	public void completeTransaction() {	
		Boolean success = false;
		
		try {
			drinkDispensed = dispenseCtrl.dispenseDrink(selection);
			if (!drinkDispensed) {
				terminateFault();			
				paymentController.refundPayment();
			}
			else if (price <= totalCollected) {
				success = paymentController.completePayment();
			}
			
		} catch (VMCSException ex) {
			terminateFault();
		}
	}

	public void terminateFault() {
		dispenseCtrl.allowSelection(false);
	}

	public void terminateTransaction() {
		dispenseCtrl.allowSelection(false);
		
		getPaymentController().refundPayment();
		cpanel.setStateTerminateButton(false);
	}

	public void cancelTransaction() {
		getPaymentController().refundPayment();
		dispenseCtrl.allowSelection(true);
	}

	public void closeDown() {
		if (cpanel != null) {
			cpanel.closeDown();
		}
		getPaymentController().closeDown();
	}

	public void displayCustomerPanel() {
		SimulatorControlPanel scp = mainCtrl.getSimulatorControlPanel();
		if (cpanel == null)
			cpanel = new CustomerPanel((Frame) scp, this);
		cpanel.display();

		dispenseCtrl.updateDrinkPanel();
		dispenseCtrl.allowSelection(true);
		getPaymentController().displayPaymentPanel();
	}

	public void refreshCustomerPanel() {
		dispenseCtrl.updateDrinkPanel();
		mainCtrl.getSimulatorControlPanel().setActive(4, false);
		dispenseCtrl.allowSelection(true);
		cpanel.setStateTerminateButton(true);
		getPaymentController().refreshPaymentPanel();
	}

	public CustomerPanel getCustomerPanel() {
		return cpanel;
	}

	public MainController getMainController() {
		return mainCtrl;
	}

	public StoreController getStoreController() {
		return storeCtrl;
	}
	
	public DispenseController getDispenseController(){
		return dispenseCtrl;
	}
	
	public PaymentController getPaymentController(){
		return paymentController;
	}

}
